﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
using WFNetLib;
using System.Diagnostics;
using System.Collections;
using System.Threading;
using WFNetLib.StringFunc;

namespace 生命体征测试仪
{    
    public partial class formMedical : formBase
    {       
        CreativePacket XinDianPacket;
        private bool XinDian_ComListening = false;//是否没有执行完invoke相关操作              
        private bool XinDian_ComClosing = false;//是否正在关闭串口，执行Application.DoEvents， 并阻止再次invoke 
        Queue XinDianQueue;
        bool bXinDianPacketProc;
        private void tabXinDian_Enter(object sender, EventArgs e)
        {
            leftTime = ExitTime;
            if(SysConfig.XinDianCom!=null)
            {
                XinDianPacket = new CreativePacket();
                SysConfig.XinDianCom.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(XinDianCom_DataReceived);
                XinDianQueue = new Queue();
                bXinDianPacketProc = true;
                XinDian_ComListening = false;
                XinDian_ComClosing = false;
                Thread th = new Thread(new ThreadStart(XinDianPacketProc));
                th.Start();
            }
            //return true;
        } 
//         bool InitXinDian()
//         {
//             
//         }
        private void tabXinDian_Leave(object sender, EventArgs e)
        {
            leftTime = ExitTime;
            if (SysConfig.XinDianCom != null)
            {
                XinDian_ComClosing = true;
                while (XinDian_ComListening)
                    Application.DoEvents();
                try
                {
                    SysConfig.XinDianCom.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(XinDianCom_DataReceived);
                }
                catch { }
                bXinDianPacketProc = false;
            }
        }
        void XinDianPacketProc()
        {
            bool bRange = false;
            List<ushort> XinDianDatas=new List<ushort>();
            while (bXinDianPacketProc)
            {
                if (XinDianQueue.Count != 0)
                {
                    CreativePacket XinDianPacket;
                    lock (XinDianQueue.SyncRoot)
                    {
                        XinDianPacket = (CreativePacket)XinDianQueue.Dequeue();
                    }
                    if (XinDianPacket.Header.Command == 0x30)
                    {
                        if (XinDianPacket.Header.type == 0x01)
                        {
                            XinDian_IsStart = false;
                            this.Invoke((EventHandler)(delegate
                            {
                                XinDianState.Text = "开始测量";
                                XinDianResult.Visible = false;
                                chart1.Series[0].Points.Clear();
                                chart2.Series[0].Points.Clear();
                                chart3.Series[0].Points.Clear();
                                XinDianDatas = new List<ushort>();
                            }));
                        }
                        else if (XinDianPacket.Header.type == 0x02)
                        {
                            XinDian_IsStart = false;
                            this.Invoke((EventHandler)(delegate
                            {
                                XinDianState.Text = "停止测量";
                            }));
                        }
                    }
                    if (XinDianPacket.Header.Command == 0x32)
                    {
                        if (!bRange)
                        {
                            if (BytesOP.GetBit(XinDianPacket.Data[1], 7))
                            {
                                this.Invoke((EventHandler)(delegate
                                {
                                    chart1.ChartAreas[0].AxisY.Maximum = 4095;
                                    chart2.ChartAreas[0].AxisY.Maximum = 4095;
                                    chart3.ChartAreas[0].AxisY.Maximum = 4095;
                                }));
                            }
                            else
                            {
                                this.Invoke((EventHandler)(delegate
                                {
                                    chart1.ChartAreas[0].AxisY.Maximum = 255;
                                    chart2.ChartAreas[0].AxisY.Maximum = 255;
                                    chart3.ChartAreas[0].AxisY.Maximum = 255;
                                }));
                            }
                        }
                        if (!XinDian_IsStart)
                        {
                            if (XinDianPacket.Data[0] != 0)
                            {
                                XinDian_IsStart = true;
                                this.Invoke((EventHandler)(delegate
                                {
                                    chart1.Series[0].Points.Clear();
                                    chart2.Series[0].Points.Clear();
                                    chart3.Series[0].Points.Clear();
                                }));
                            }
                        }
                        Debug.WriteLine(XinDianPacket.Data[0].ToString());                        
                        this.Invoke((EventHandler)(delegate
                        {
                            XinDian_XinTiao.Visible = false;
                            for (int i = 0; i < 25;i++ )
                            {
                                if (BytesOP.GetBit(XinDianPacket.Data[1 + i * 2], 6))
                                {
                                    XinDian_XinTiao.Visible = true;
                                    break;
                                }
                            }
                            for (int i = 0; i < 25; i++)
                            {
                                ushort xd;
                                if (BytesOP.GetBit(XinDianPacket.Data[1 + i * 2], 7))
                                {
                                    xd = BytesOP.MakeShort(BytesOP.GetLowNibble(XinDianPacket.Data[1 + i * 2]), XinDianPacket.Data[1 + i * 2 + 1]);
                                }
                                else
                                {
                                    xd = BytesOP.MakeShort(0, XinDianPacket.Data[1 + i * 2 + 1]);
                                }
                                if (XinDian_IsStart)
                                {
                                    if (XinDianPacket.Data[0] < 68)
                                    {
                                        chart1.Series[0].Points.AddXY((XinDianPacket.Data[0]-1)*25+i, xd);
                                    }
                                    else if (XinDianPacket.Data[0] < 135)
                                    {
                                        chart2.Series[0].Points.AddXY((XinDianPacket.Data[0]-67 - 1) * 25 + i, xd);
                                    }
                                    else
                                    {
                                        chart3.Series[0].Points.AddXY((XinDianPacket.Data[0] -134- 1) * 25 + i, xd);
                                        if (XinDianPacket.Data[0] > 195)
                                        {
                                            XinDianResult.Visible = true;
                                            XinDianResult.Text = "正在分析";
                                            timerXinTiao.Enabled = true;
                                        }
                                    }
                                    XinDianDatas.Add(xd);
                                }
                                else
                                {
                                    if (chart1.Series[0].Points.Count > 1670)
                                    {
                                        chart1.Series[0].Points.Clear();
                                    }
                                    chart1.Series[0].Points.AddY(xd);
                                }
                                if (XinDianPacket.Data[52] != 0)
                                {
                                    XinDian_DaoLianTuoLuo.Visible = true;
                                }
                                else
                                {
                                    XinDian_DaoLianTuoLuo.Visible = false;
                                }
                            }
                        }));
                    }
                    if (XinDianPacket.Header.Command == 0x33)
                    {
                        this.Invoke((EventHandler)(delegate
                        {
                            XinDianState.Text = "测量完成";
                            Common.XinDianAnalyseResult r = (Common.XinDianAnalyseResult)XinDianPacket.Data[0];
                            MedicalResult.XinDianResult = XinDianPacket.Data[0];
                            MedicalResult.XinDianXinLv = XinDianPacket.Data[2];
                            MedicalResult.XindianDatas = StringsFunction.ushortToHexStr(XinDianDatas, "");
                            XinDianResult.Text = "分析结果为:" + r.ToString() + ",心率值为:" + XinDianPacket.Data[2].ToString();
                            timerXinTiao.Enabled = false;
                            bChange = true;
                        }));
                    }
                }
            }
        }
        private void timerXinTiao_Tick(object sender, EventArgs e)
        {
            timerXinTiao.Enabled = false;
            this.Invoke((EventHandler)(delegate
            {
                XinDianState.Text = "测量完成";
                XinDianResult.Text = "无法得到分析结果，请重试";
            }));
        }   
        bool XinDian_IsStart = false;
        private void XinDianCom_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (XinDian_ComClosing)
                return;
            XinDian_ComListening = true;
            int rxn = SysConfig.XinDianCom.BytesToRead;
            while (rxn != 0)
            {
                rxn--;
                byte rx = (byte)SysConfig.XinDianCom.ReadByte();
                if (XinDianPacket.DataPacketed(rx))
                {
                    if (XinDianPacket.Header.Command!=0x31)
                    {
                        lock (XinDianQueue.SyncRoot)
                        {
                            XinDianQueue.Enqueue(XinDianPacket);
                        }
                    }              
                    XinDianPacket = new CreativePacket();
                }
            }
            
            XinDian_ComListening = false;
        }
    }
}
